/*********************************************************************************
 *
 *        SolarDrawMatrix.java
 *
 *    3D Matrix for use in solar system drawer
 *
 *********************************************************************************
 *    Copyright 2003 Brown University -- Steven P. Reiss
 *********************************************************************************
 *  Copyright 2003, Brown University, Providence, RI.
 *
 *              All Rights Reserved
 *
 *  Permission to use, copy, modify, and distribute this software and its
 *  documentation for any purpose other than its incorporation into a
 *  commercial product is hereby granted without fee, provided that the
 *  above copyright notice appear in all copies and that both that
 *  copyright notice and this permission notice appear in supporting
 *  documentation, and that the name of Brown University not be used in
 *  advertising or publicity pertaining to distribution of the software
 *  without specific, written prior permission.
 *
 *  BROWN UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 *  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 *  FITNESS FOR ANY PARTICULAR PURPOSE.  IN NO EVENT SHALL BROWN UNIVERSITY
 *  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
 *  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 *  WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 *  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 *  OF THIS SOFTWARE.
 *
 ********************************************************************************/
/* RCS: $Header$ */
/*********************************************************************************
 *
 * $Log$
 *
 ********************************************************************************/
package solardraw;
class SolarDrawMatrix {
    /********************************************************************************/
    /* Private Storage */
    /********************************************************************************/
    private double[][] m_v;
    /********************************************************************************/
    /* Constructors */
    /********************************************************************************/
    SolarDrawMatrix() {
        m_v = new double[4][4];
        zero();
    }
    /********************************************************************************/
    /* Basic setting methods */
    /********************************************************************************/
    void zero() {
        for (int i = 0; i < 4; ++i) {
            for (int j = 0; j < 4; ++j) {
                m_v[i][j] = 0;
            }
        }
    }
    void identity() {
        zero();
        for (int i = 0; i < 4; ++i) {
            m_v[i][i] = 1.0;
        }
    }
    void translate(SolarDrawVector v, double scale) {
        identity();
        m_v[3][0] = v.getX() * scale;
        m_v[3][1] = v.getY() * scale;
        m_v[3][2] = v.getZ() * scale;
    }
    void rotateDeg(SolarDrawVector v0, double deg) {
        double rad = Math.PI * deg / 180.0;
        rotateRad(v0, rad);
    }
    void rotateRad(SolarDrawVector v0, double rad) {
        SolarDrawVector v = new SolarDrawVector(v0);
        v.normalize();
        double d = Math.hypot(v.getY(), v.getZ());
        identity();
        if (d != 0) {
            m_v[1][1] = v.getZ() / d;
            m_v[1][2] = v.getY() / d;
            m_v[2][1] = -v.getY() / d;
            m_v[2][2] = v.getZ() / d;
        }
        SolarDrawMatrix ry = new SolarDrawMatrix();
        ry.identity();
        ry.m_v[0][0] = d;
        ry.m_v[0][2] = v.getX();
        ry.m_v[2][0] = -v.getX();
        ry.m_v[2][2] = d;
        SolarDrawMatrix rd = new SolarDrawMatrix();
        rd.identity();
        rd.m_v[0][0] = Math.cos(rad);
        rd.m_v[0][1] = Math.sin(rad);
        rd.m_v[1][0] = -rd.m_v[0][1];
        rd.m_v[1][1] = rd.m_v[0][0];
        SolarDrawMatrix riy = new SolarDrawMatrix();
        SolarDrawMatrix rix = new SolarDrawMatrix();
        for (int i = 0; i < 4; ++i) {
            for (int j = 0; j < 4; ++j) {
                riy.m_v[i][j] = ry.m_v[i][j];
                rix.m_v[i][j] = m_v[i][j];
            }
        }
        riy.m_v[0][2] = -ry.m_v[0][2];
        riy.m_v[2][0] = -ry.m_v[2][0];
        rix.m_v[1][2] = -m_v[1][2];
        rix.m_v[2][1] = -m_v[2][1];
        multiply(this, ry);
        multiply(this, rd);
        multiply(this, riy);
        multiply(this, rix);
    }
    /********************************************************************************/
    /* Operations */
    /********************************************************************************/
    double get(int x, int y) {
        return m_v[x][y];
    }
    void leftMult(SolarDrawMatrix m) {
        multiply(m, this);
    }
    private void multiply(SolarDrawMatrix m1, SolarDrawMatrix m2) {
        double[][] r = new double[4][4];
        for (int i = 0; i < 4; ++i) {
            for (int j = 0; j < 4; ++j) {
                double v = 0;
                for (int k = 0; k < 4; ++k) {
                    v += m1.m_v[i][k] * m2.m_v[k][j];
                }
                r[i][j] = v;
            }
        }
        for (int i = 0; i < 4; ++i) {
            for (int j = 0; j < 4; ++j) {
                m_v[i][j] = r[i][j];
            }
        }
    }
} // end of class SolarDrawMatrix
/* end of SolarDrawMatrix */

